﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using Transcend.Archive.CSScan.Store.Contract;
using Transcend.Utility;
namespace Transcend.Archive.CSScan.Stores
{

    /// <summary>
    /// 存储工厂，存储采用工厂模式，外部调用不需要具体实现
    /// </summary>
    public class StoreFactory
    {
        /// <summary>
        /// 获取图像的存储
        /// </summary>
        /// <param name="imageNo">图像Id</param>
        /// <returns></returns>
        public static ImageStore GetStore(decimal imageNo)
        {
            return GetStore(imageNo, "");
        }
        /// <summary>
        /// 获取图像存储实例
        /// </summary>
        /// <param name="imageNo">图像Id</param>
        /// <param name="scanDbUser">扫描数据库所在用户</param>
        /// <returns></returns>
        public static ImageStore GetStore(decimal imageNo, string scanDbUser)
        {
            using (var conn = Db.GetConnection())
            {
                return GetStore(conn, imageNo, scanDbUser);
            }
        }
        /// <summary>
        /// 获取存储
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="imageNo">图形Id</param>
        /// <param name="scanDbUser">扫描用户名</param>
        /// <returns></returns>
        public static ImageStore GetStore(System.Data.Common.DbConnection conn, decimal imageNo, string scanDbUser)
        {
            var user = scanDbUser;
            if (!string.IsNullOrEmpty(user)) user += ".";

            using (var cmd = conn.CreateCommand())
            {
                string sql = "select s.Store_Id from {ScanUser}DS_Instance s,{ScanUser}DS_Item i,{ScanUser}DS_Page p " +
                  "  where s.ID=i.Inst_ID and i.ID=p.Item_Id and p.ID={0}";
                sql = sql.Replace("{ScanUser}", user);
                var storeId = Db.ExecuteScaler<decimal>(conn, sql, imageNo);

                if (storeId == 0)
                {
                    throw new Exception(string.Format("图像[{0}]对应的实例没有定义存储。", imageNo));
                }

                sql = "Select STORE_NAME,STORE_DEFINE,IOC_ID From {ScanUser}DS_STORE where ID={0}  AND IS_VALID=1";
                sql = sql.Replace("{ScanUser}", user);
                Db.InitCommand(cmd, sql, storeId);
                string springId, storeName, storeDesc;
                using (var reader = cmd.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        reader.Close();
                        throw new Exception(string.Format("图像[{0}]定义的存储[{1}]不存在。", imageNo, storeId));
                    }

                    springId = Db.GetValue<string>(reader, "IOC_ID");  //图像定义存储类
                    storeName = Db.GetValue<string>(reader, "STORE_NAME");  //图像定义存储名称
                    storeDesc = Db.GetValue<string>(reader, "STORE_DEFINE");  //图像定义存储名称
                    reader.Close();
                }
                if (string.IsNullOrEmpty(springId))
                {
                    throw new Exception(string.Format("图像[{0}]定义的存储[{1}]缺少实现程序。", imageNo, storeId));
                }
                if (string.IsNullOrEmpty(storeDesc))
                {
                    throw new Exception(string.Format("图像[{0}]定义的存储[{1}]缺少描述信息。", imageNo, storeId));
                }
                var store = SpringHelper.Get<ImageStore>(springId);
                store.StoreId = storeId;
                store.Parse(storeDesc);
                return store;
            }

        }

        /// <summary>
        /// 根据StoreId获取Store
        /// </summary>
        /// <param name="storeId"></param>
        /// <returns></returns>
        public static ImageStore GetStoreByStoreId(decimal storeId)
        {
            using (var conn = Db.GetConnection())
            {
                return GetStoreByStoreId(conn, storeId);
            }
        }

        /// <summary>
        /// 根据StoreId获取Store
        /// </summary>
        /// <param name="conn">当前连接</param>
        /// <param name="storeId">存储Id</param>
        /// <returns></returns>
        public static ImageStore GetStoreByStoreId(DbConnection conn, decimal storeId)
        {
            return GetStoreByStoreId(conn, storeId, "");
        }

        /// <summary>
        /// 根据StoreId获取Store
        /// </summary>
        /// <param name="conn">当前连接</param>
        /// <param name="storeId">存储Id</param>
        /// <param name="scanDbUser">存储所在的数据库用户</param>
        /// <returns></returns>
        public static ImageStore GetStoreByStoreId(DbConnection conn, decimal storeId, string scanDbUser)
        {
            var user = scanDbUser;
            if (!string.IsNullOrEmpty(user)) user += ".";
            string sql = "SELECT STORE_NAME,STORE_DEFINE,IOC_ID FROM {ScanUser}DS_STORE WHERE ID={0} AND IS_VALID=1";
            sql = sql.Replace("{ScanUser}", user);

            string springId, storeName, storeDesc;

            using (var cmd = conn.CreateCommand())
            {
                Db.InitCommand(cmd, sql, storeId);
                using (var reader = cmd.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        reader.Close();
                        throw new Exception(string.Format("系统存储Id[{0}]不存在。", storeId));
                    }

                    springId = Db.GetValue<string>(reader, "IOC_ID");  //图像定义存储类
                    storeName = Db.GetValue<string>(reader, "STORE_NAME");  //图像定义存储名称
                    storeDesc = Db.GetValue<string>(reader, "STORE_DEFINE");  //图像定义存储名称       
                }

                if (string.IsNullOrEmpty(springId))
                {
                    throw new Exception(string.Format("存储[{0}] 缺少实现程序[{1}]。", storeId, storeId));
                }
                if (string.IsNullOrEmpty(storeDesc))
                {
                    throw new Exception(string.Format("存储[{0}]的缺少程序[{1}]描述信息。", storeId, storeId));
                }
                var store = SpringHelper.Get<ImageStore>(springId);
                store.StoreId = storeId;
                store.Parse(storeDesc);
                return store;
            }


        }


        /// <summary>
        /// 获取存储
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="pkValue">主键值</param>
        /// <param name="appTypeId">应用Id</param>
        /// <param name="scanDbUser">扫描用户</param>
        /// <param name="instid">实例Id</param>
        /// <returns>存储实例</returns>
        public static ImageStore GetDsStore(System.Data.Common.DbConnection conn, string pkValue, decimal appTypeId, string scanDbUser, decimal instid = 0M)
        {
            var sql = "SELECT STORE_ID FROM {dsstore}  where ID=:ID AND IS_VALID=1";
            sql = sql.Replace("{dsstore}", GetQualifiedName(scanDbUser, "DS_APP"));
            decimal storeId = 0M;
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = sql;
                var p = cmd.CreateParameter();
                p.ParameterName = ":ID";
                p.Value = appTypeId;
                cmd.Parameters.Add(p);

                storeId = Convert.ToDecimal(cmd.ExecuteScalar());
            }

            return GetDsStore(conn, storeId, scanDbUser);
        }

        /// <summary>
        /// 获取存储
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="storeId">存储Id</param>
        /// <param name="scanDbUser">扫描用户</param>
        /// <returns>存储实例</returns>
        public static ImageStore GetDsStore(System.Data.Common.DbConnection conn, decimal storeId, string scanDbUser)
        {
            var sql = string.Empty;
            using (var cmd = conn.CreateCommand())
            {
                //SELECT STORE_NAME,STORE_DEFINE,IOC_ID FROM {dsstore} WHERE ID=:ID AND IS_VALID=1
                sql = "SELECT STORE_NAME,STORE_DEFINE,IOC_ID FROM {dsstore} WHERE ID={0} AND IS_VALID=1";
                sql = sql.Replace("{dsstore}", GetQualifiedName(scanDbUser, "DS_STORE"));
                Db.InitCommand(cmd, sql, storeId);
                string springId, storeName, storeDesc;
                using (var reader = cmd.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        reader.Close();
                        throw new Exception(string.Format("存储[{0}]不存在。", storeId));
                    }
                    springId = Db.GetValue<string>(reader, "IOC_ID");  //图像定义存储类
                    storeName = Db.GetValue<string>(reader, "STORE_NAME");  //图像定义存储名称
                    storeDesc = Db.GetValue<string>(reader, "STORE_DEFINE");  //图像定义存储名称
                    reader.Close();
                }
                if (string.IsNullOrEmpty(springId))
                {
                    throw new Exception(string.Format("存储[{0}]缺少实现程序。", storeId));
                }
                if (string.IsNullOrEmpty(storeDesc))
                {
                    throw new Exception(string.Format("存储[{0}]缺少描述信息。", storeId));
                }

                var store = SpringHelper.Get<ImageStore>(springId);
                store.StoreId = storeId;
                store.Parse(storeDesc);
                return store;
            }
        }

        /// <summary>
        /// 根据图像Id获取图像
        /// </summary>
        /// <param name="imageNo">图形Id</param>
        /// <returns>图形字节数据</returns>
        public static byte[] GetImage(decimal imageNo)
        {
            return GetImage(imageNo, "");
        }
        /// <summary>
        /// 根据图像Id获取图像
        /// </summary>
        /// <param name="imageNo">图像Id</param>
        /// <param name="scanDbUser">扫描用户</param>
        /// <returns>图形字节数据</returns>
        public static byte[] GetImage(decimal imageNo, string scanDbUser)
        {
            using (var conn = Db.GetConnection())
            {
                return GetImage(conn, imageNo, scanDbUser);
            }
        }
        /// <summary>
        /// 获取图形
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="imageNo">图形Id</param>
        /// <param name="scanDbUser">扫描用户</param>
        /// <returns>图形字节数据</returns>
        public static byte[] GetImage(System.Data.Common.DbConnection conn, decimal imageNo, string scanDbUser)
        {
            ScanImage img = null;
            string sql = "select i.Inst_ID, d.Folder, p.Raw_File_Name,p.ID from {dsinstance} d, {dsitem} i,{dspage} p  where d.ID=i.Inst_ID And i.ID=p.Item_Id and p.ID={0}";
            sql = sql.Replace("{dsinstance}", GetQualifiedName(scanDbUser, "DS_Instance"));
            sql = sql.Replace("{dsitem}", GetQualifiedName(scanDbUser, "DS_Item"));
            sql = sql.Replace("{dspage}", GetQualifiedName(scanDbUser, "DS_Page"));

            using (var cmd = conn.CreateCommand())
            {
                Db.InitCommand(cmd, sql, imageNo);
                using (var dr = cmd.ExecuteReader())
                {
                    if (dr.Read())
                    {
                        img = new ScanImage
                        {
                            InstanceId = Transcend.Utility.Db.GetValue<decimal>(dr, "Inst_ID"),
                            Tag = Transcend.Utility.Db.GetValue<string>(dr, "Folder"),
                            FileName = Transcend.Utility.Db.GetValue<string>(dr, "Raw_File_Name"),
                            ImageNo = Transcend.Utility.Db.GetValue<decimal>(dr, "ID")
                        };
                    }
                }
            }

            if (img.InstanceId == 0)
            {
                throw new Exception(string.Format("图像[{0}]的扫描实例不存在。", imageNo));
            }
            using (var store = GetStore(conn, imageNo, scanDbUser))
            {
                return store.GetImage(img.InstanceId, img.ImageNo);
            }
        }

        /// <summary>
        /// 获取存储的表限定名
        /// </summary>
        /// <param name="user">数据库用户</param>
        /// <param name="objectName">对象名称</param>
        /// <returns>表名</returns>
        protected static string GetQualifiedName(string user, string objectName)
        {
            var qName = objectName;
            if (!string.IsNullOrEmpty(user))
            {
                qName = string.Format("{0}.{1}", user, objectName);
            }

            return qName;
        }
    }
}
